package com.shylock.as.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.shylock.as.dao.UserDao;
import com.shylock.as.dao.UserLogDao;
import com.shylock.as.entity.User;
import com.shylock.as.entity.UserLog;
import com.shylock.as.service.intf.UserService;
import com.shylock.as.util.JedisUtil;
import com.shylock.as.util.JwtUtils;
import com.shylock.common.bo.UserBo;
import com.shylock.common.bo.UserCodeBo;
import com.shylock.common.config.RedisKeyConfig;
import com.shylock.common.config.SystemConfig;
import com.shylock.common.util.BeanUtil;
import com.shylock.common.util.EncryptUtil;
import com.shylock.common.util.RUtils;
import com.shylock.common.util.StringUtils;
import com.shylock.common.vo.R;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.swing.*;
import java.util.Date;


@Service
public class UserServiceImpl implements UserService {
    @Resource
    private UserDao dao;
    @Resource
    private UserLogDao logDao;
    
    @Value("${cs.pass.prikey}")
    private String prikey;

    @Override
    public R checkPhone(String phone) {
        //入参校验
        if(StringUtils.regexPhone(phone)){
            //查询数据库，没有此数据允许进行下一步
            if(dao.selectOne(new QueryWrapper<User>().eq("phone",phone))==null){
                return RUtils.ok(null);
            }
        }
        return RUtils.fail();
    }
    @Override
    @Transactional
    public R register(UserBo bo, String ip) {//注册手机号密码登录
       
        //校验接收数据是否为空
        if(bo!=null){
            if(StringUtils.isNotEmpty(bo.getPassword())&&StringUtils.regexPhone(bo.getPhone())){
               
                //验证是否经过验证码校验
                if(JedisUtil.checkSet(RedisKeyConfig.REGISTER_PHONES,bo.getPhone())){
                    //校验手机号是否存在
                    if(dao.selectOne(new QueryWrapper<User>().eq("phone",bo.getPhone()))==null){
                        
                        //组装注册的对象
                        User user = BeanUtil.copyProperty(User.class, bo, bo.getClass().getDeclaredFields());
                        
                        //用户状态处理
                        user.setFlag(SystemConfig.USER_FLAG_OK);
                        //密文处理
                        user.setPassword(EncryptUtil.rsaEnc(prikey,user.getPassword()));
                     
                        //新增数据
                        if(dao.insert(user)>0){
                            logDao.insert(new UserLog(user.getId(),SystemConfig.USER_OP_ADD,"注册新用户，注册密码",ip,new Date()));
                            return RUtils.ok(null);
                        }
                    }
                }
            }
        }
        return RUtils.fail("失败");
    }

  

    @Override
    public R loginPassword(UserBo bo, String ip) {
        //校验
        if(bo!=null){
            if(StringUtils.isNotEmpty(bo.getPassword())&&StringUtils.regexPhone(bo.getPhone())){
                //查询数据库
                User user = dao.selectOne(new QueryWrapper<User>().eq("phone", bo.getPhone()));
                if(user!=null){
                    //校验用户状态是否可用
                    if(user.getFlag()==SystemConfig.USER_FLAG_OK){
                        //验证密码
                        if(user.getPassword().equals(EncryptUtil.rsaEnc(prikey,bo.getPassword()))){
                            //校验当前用户是否已登录，已登录则不允许再次登录
                            if(!JedisUtil.checkKey(RedisKeyConfig.LOGIN_PHONE+bo.getPhone())){
                                String token= JwtUtils.createToken(user.getId()+"");
                                //Redis 存储 性能+有效期 唯一登录 String类型
                                //当前令牌：令牌对应客户信息，存入Redis可通过key获取用户信息
                                JedisUtil.addStr(RedisKeyConfig.LOGIN_TOKEN+token, JSON.toJSONString(user),RedisKeyConfig.LOGIN_TOKEN_TIME);
                                //当前令牌:手机号令牌，验证唯一登录
                                JedisUtil.addStr(RedisKeyConfig.LOGIN_PHONE+bo.getPhone(),token,RedisKeyConfig.LOGIN_TOKEN_TIME);
                                logDao.insert(new UserLog(user.getId(),SystemConfig.USER_OP_LOGIN,"手机号密码登录成功",ip,new Date()));
                                return RUtils.ok(token);
                            }else {
                                return RUtils.fail("亲，您已登录，不可重复登录");
                            }
                        }else{
                            return RUtils.fail("亲，密码错误");
                        }
                    }else{
                        return RUtils.fail("亲，账号状态不可用");
                    }
                }else{
                    return RUtils.fail("亲，此账号未注册");
                }

            }else{
                return RUtils.fail("亲，输入内容不合法");
            }
        }
        return RUtils.fail("亲，账号或密码错误");
    }

    @Override
    @Transactional
    public R loginCode(UserCodeBo bo, String ip) {
        //校验输入内容
        if(bo!=null){
            //校验手机号
            if(StringUtils.regexPhone(bo.getPhone())){
                if(JedisUtil.checkKey(RedisKeyConfig.SMS_LCODE+bo.getPhone())){
                    if(bo.getCode()==Integer.parseInt(JedisUtil.getStr(RedisKeyConfig.SMS_LCODE+bo.getPhone()))){
                        //验证用户是否在线
                        if(!JedisUtil.checkKey(RedisKeyConfig.LOGIN_PHONE+bo.getPhone())){
                         
                            //校验当前账号是否为用户已注册账号信息，如果不是，自动注册
                            User user= dao.selectOne(new QueryWrapper<User>().eq("phone",bo.getPhone()));
                            if(user==null) {
                                user.setPassword(EncryptUtil.rsaEnc(prikey, bo.getCode() + ""));
                                user.setFlag(SystemConfig.USER_FLAG_OK);
                                user.setPhone(bo.getPhone());
                                dao.insert(user);
                                logDao.insert(new UserLog(user.getId(), SystemConfig.USER_OP_ADD, "用户验证码登录，用户不存在自动注册", ip, new Date()));
                            }
                            String token = JwtUtils.createToken(user.getId()+"");
                            //当前令牌：可通过此令牌获取用户信息
                            JedisUtil.addStr(RedisKeyConfig.LOGIN_TOKEN+token,JSON.toJSONString(user),RedisKeyConfig.LOGIN_TOKEN_TIME);
                            //手机令牌，验证唯一登录
                            JedisUtil.addStr(RedisKeyConfig.LOGIN_PHONE+bo.getPhone(),token,RedisKeyConfig.LOGIN_TOKEN_TIME);
                            logDao.insert(new UserLog(user.getId(),SystemConfig.USER_OP_LOGIN,"手机验证码登录成功",ip,new Date()));
                            //销毁登录验证码
                            JedisUtil.delKey(RedisKeyConfig.SMS_LCODE+bo.getPhone());
                            
                            return RUtils.ok(token);
                        }else {
                            return RUtils.fail("亲，您已经在线，不可重复登录哦");
                        }
                        
                    }else{
                        return RUtils.fail("亲，验证码输入错误");
                    }
                }else{
                    return RUtils.fail("亲，手机号不合法");
                }
            }
        }
        return RUtils.fail("亲，输入有误");
    }

    @Override
    public R findPassword(UserCodeBo bo, String ip) {
        //校验非空
        if(bo!=null){
            //验证手机号格式
            if(StringUtils.regexPhone(bo.getPhone())){
                String key = RedisKeyConfig.SMS_FCODE+bo.getPhone();
                //验证验证码
                if(JedisUtil.checkKey(key)){
                    if(bo.getCode()==Integer.parseInt(JedisUtil.getStr(key))){
                        //查询数据库
                        if(dao.selectOne(new QueryWrapper<User>().eq("phone",bo.getPhone()))!=null){
                            //删除验证码，同时记录验证过的账号
                            JedisUtil.delKey(key);
                            JedisUtil.addSet(RedisKeyConfig.FIND_PHONES,bo.getPhone());
                            return RUtils.ok(null);
                            
                        }else{
                            RUtils.fail("亲，手机号未注册");
                        }
                        
                    }else{
                        RUtils.fail("亲，验证码错误");
                    }
                }
            }else{
                RUtils.fail("亲，手机号格式不正确");
            }
        }
        return RUtils.fail("亲，有故障");
    }

    @Override
    @Transactional
    public R updatePassword(UserBo bo, String ip) {
        //校验非空
        if(bo!=null){
            if(StringUtils.regexPhone(bo.getPhone())&&StringUtils.isNotEmpty(bo.getPassword())){
                String key = RedisKeyConfig.FIND_PHONES;
                if(JedisUtil.checkSet(key,bo.getPhone())){
                    //修改密码
                    dao.updatePass(EncryptUtil.rsaEnc(prikey,bo.getPassword()),bo.getPhone());
                    logDao.insert(new UserLog(-1,SystemConfig.USER_OP_FIND,"手机号验证码找回密码成功",ip,new Date()));
                    JedisUtil.delSet(key,bo.getPhone());
                    //如果当前账号存在需要删除清空
                   String keyPhone =  RedisKeyConfig.LOGIN_PHONE+bo.getPhone();
                   if(JedisUtil.checkKey(keyPhone)){
                       JedisUtil.delKey(RedisKeyConfig.LOGIN_TOKEN+JedisUtil.getStr(keyPhone));
                       JedisUtil.delKey(keyPhone);
                   }
                   return RUtils.ok(null);
                }else{
                    return RUtils.fail("账号未验证");
                }
            }else{
                return RUtils.fail("亲，格式不正确");
            }
        }
        return RUtils.fail("亲，账号或者密码输入有误");
    }

    @Override
    public R checkToken(String token) {
        //非空校验
        if(StringUtils.isNotEmpty(token)){
            if(JedisUtil.checkKey(RedisKeyConfig.LOGIN_TOKEN+token)){
                return RUtils.ok("令牌有效");
            }
        }
        return RUtils.fail("无效令牌");
    }

    @Override
    public R loginOut(String token) {
        //非空判断
        if(StringUtils.isNotEmpty(token)){
            //校验令牌
            String key = RedisKeyConfig.LOGIN_TOKEN+token;
            if(JedisUtil.checkKey(key)){
                //清理
                User user = JSON.parseObject(JedisUtil.getStr(key),User.class);
                JedisUtil.delKey(RedisKeyConfig.LOGIN_PHONE+user.getPhone());
                JedisUtil.delKey(key);
                return RUtils.ok("注销成功");
            }else {
                return RUtils.fail("令牌无效");
            }
            
        }
        return RUtils.fail("注销失败");
    }

    @Override
    public R queryUserInfo(String token) {
        //入参校验
        if(StringUtils.isNotEmpty(token)){
            //校验令牌
            String key = RedisKeyConfig.LOGIN_TOKEN+token;
            if(JedisUtil.checkKey(key)){
                //获取令牌对应的用户信息
                User user = JSON.parseObject(JedisUtil.getStr(key),User.class);
                user.setPassword("");//数据脱敏
                return RUtils.ok(user);
            }
        }
        return RUtils.fail("亲，令牌有误");
    }

}
